package com.lmk.ms.common.net.tcp.server.service.impl;

import com.lmk.ms.common.net.tcp.server.service.TcpServerService;
import lombok.extern.slf4j.Slf4j;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;

/**
 * TCP服务端业务服务适配器
 * @author laomake@hotmail.com
 * @version 1.0
 * @date 2023/4/25
 */
@Slf4j
public abstract class TcpServerServiceAdapter implements TcpServerService {
    @Override
    public void handel(Socket socket) {
        if(socket == null){
            log.error("业务处理失败，socket不可为空！");
            return;
        }

        log.debug("启动新的业务处理线程");
        new Thread(new SimpleSocketService(socket)).start();
    }

    /**
     * 子类重写该方法时，不要处理IO异常
     * @param in
     * @param out
     * @throws Exception
     */
    public abstract void service(DataInputStream in, DataOutputStream out) throws IOException;

    /**
     * 处理socket业务
     */
    class SimpleSocketService implements Runnable{
        Socket socket;

        public SimpleSocketService(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try(
                DataInputStream in = new DataInputStream(socket.getInputStream());
                DataOutputStream out = new DataOutputStream(socket.getOutputStream())
            ) {
                log.debug("业务处理线程已启动，开始处理socket数据");
                service(in, out);
            }catch (EOFException e) {
                log.info("客户端socket已关闭");
            } catch (IOException e) {
                log.info("业务处理线程业务异常：", e);
            } finally {
                if(socket != null){
                    try {
                        log.debug("业务处理线程关闭socket");
                        socket.close();
                    } catch (IOException e) {
                        log.error("业务处理线程关闭socket异常：", e);
                    }
                }
            }
            log.debug("业务处理线程退出");
        }
    }
}
